package com.liyunc.demo.aop;

import com.liyunc.demo.annotation.NoRepeatSubmitToken;
import com.liyunc.demo.enums.ResultCode;
import com.liyunc.demo.result.CommonResult;
import com.liyunc.demo.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 定义切面类.
 * Aop处理拦截.
 */
@Slf4j
@Aspect
@Component
public class TokenAspect {

    //使用AOP环绕通知拦截所有访问（controller）
    @Pointcut("execution(public * com.liyunc.demo.controller.*.*(..))")
    public void extAop() {
    }

    //环绕通知
    @Around("extAop()&&@annotation(noRepeatSubmitToken)")
    public Object testToken(ProceedingJoinPoint joinPoint, NoRepeatSubmitToken noRepeatSubmitToken)
        throws Throwable {
        // 获取request，response
        HttpServletRequest request =
            ((ServletRequestAttributes) Objects
                .requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        HttpServletResponse response =
            ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        //得到请求头是否有token，没有就从token中获取
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            token = request.getParameter("token");
        }
        log.info("token信息为：{}", token);
        //如果是第一次登录，token值为null
        if (StringUtils.isEmpty(token)) {
            return joinPoint.proceed();
        } else {
            boolean needSaveSession = noRepeatSubmitToken.save();
            log.info("noRepeatSubmitToken.save()信息为：{}", needSaveSession);
            if (needSaveSession) {
                //如果不是第一次
                //校验token的值
                boolean result = JwtUtil.validateToken(token,null);
                if (!result) {
                    log.info("token验证失败");
                    return CommonResult.failed(ResultCode.FAILED.getCode(),"token verify fail");
                } else {
                    log.info("token验证成功");
                    return CommonResult.success(ResultCode.SUCCESS);
                }
            }
        }

        //放行
        return joinPoint.proceed();
    }
}
